package com.joyveb.webtest.controller;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.List;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

@Slf4j
@Controller
@RequestMapping(value = ProxyController.MAPPER)
public class ProxyController {
	protected static final String MAPPER = "/transport";

	@Resource(name = "proxyRestTemplate")
	private RestTemplate restTemplate;

	@RequestMapping(value = "/**",method={RequestMethod.POST,RequestMethod.GET},produces={MediaType.ALL_VALUE},consumes=MediaType.ALL_VALUE)
	public ResponseEntity<Object> proxyJson(HttpServletRequest request,  @RequestBody Object body  ,@RequestHeader MultiValueMap<String, String> headers) throws UnsupportedEncodingException {
		String url = request.getRequestURI();
		String queryString = request.getQueryString();
		String contextPath = request.getContextPath();
		if (queryString != null && queryString != "") {
			url = url + "?" + queryString;
		}
		String targetUrl = getTargetUrl(contextPath,url);
		ResponseEntity<Object> result = null;
		try {
			result = restTemplate.exchange(new URI(targetUrl), HttpMethod.valueOf(request.getMethod()), new HttpEntity<Object>(body, headers), Object.class);
		} catch (HttpClientErrorException | HttpServerErrorException exp) {
			return new ResponseEntity<Object>(exp.getResponseBodyAsString(), getResponseHeaders(exp.getResponseHeaders()), exp.getStatusCode());
		} catch (Exception exp) {
			return new ResponseEntity<Object>(exp.getMessage(), getResponseHeaders(new HttpHeaders()), HttpStatus.INTERNAL_SERVER_ERROR);
		}
		return new ResponseEntity<Object>(result.getBody(), getResponseHeaders(result.getHeaders()), result.getStatusCode());
	
	}
//	@RequestMapping(value = "/**",method={RequestMethod.POST,RequestMethod.GET},produces={MediaType.ALL_VALUE},consumes=MediaType.ALL_VALUE)
//	public ResponseEntity<byte[]> proxy(HttpServletRequest request,  @RequestBody byte[] body  ,@RequestHeader MultiValueMap<String, String> headers) throws UnsupportedEncodingException {
//		String url = request.getRequestURI();
//		String queryString = request.getQueryString();
//		String contextPath = request.getContextPath();
//		if (queryString != null && queryString != "") {
//			url = url + "?" + queryString;
//		}
//		String targetUrl = getTargetUrl(contextPath,url);
//		ResponseEntity<byte[]> result = null;
//		try {
//			result = restTemplate.exchange(new URI(targetUrl), HttpMethod.valueOf(request.getMethod()), new HttpEntity<byte[]>(body, headers), byte[].class);
//		} catch (HttpClientErrorException | HttpServerErrorException exp) {
//			return new ResponseEntity<byte[]>(exp.getResponseBodyAsByteArray(), getResponseHeaders(exp.getResponseHeaders()), exp.getStatusCode());
//		} catch (Exception exp) {
//			return new ResponseEntity<byte[]>(exp.getMessage().getBytes("utf-8"), getResponseHeaders(new HttpHeaders()), HttpStatus.INTERNAL_SERVER_ERROR);
//		}
//		return new ResponseEntity<byte[]>(result.getBody(), getResponseHeaders(result.getHeaders()), result.getStatusCode());
//	}
	
	
	private String getTargetUrl(String contextPath,String url) {
		String targetUrl = StringUtils.substringAfter(url, MAPPER);
		return "http://192.168.23.76:8080/FrontImpl/api/v1/twls/registerPath" + targetUrl;
		// return "http://192.168.23.76:8080/NotifyImpl/" + targetUrl;
	}

	private HttpHeaders getResponseHeaders(HttpHeaders originHeaders) {
		// Content-Length
		HttpHeaders header = new HttpHeaders();
		for (Entry<String, List<String>> item : originHeaders.entrySet()) {
			if ("Content-Length".equals(item.getKey())) {
				log.info("remove header info::Content-Length");
				continue;
			}
			if ("Transfer-Encoding".equals(item.getKey())) {
				log.info("remove header info::Transfer-Encoding");
				continue;
			}
			header.put(item.getKey(), item.getValue());
		}
		return header;
	}

}